package com.yx.cloud.product.laser.yxcloud;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
import android.util.Base64;
import android.util.Log;

import com.google.gson.Gson;
import com.iot.base.bean.Device;
import com.iot.base.service.req.DataBag;
import com.iot.base.service.req.DataParam;
import com.iot.common.utils.Event;
import com.iot.common.utils.LogUtils;
import com.iot.common.utils.StringUtils;
import com.iot.common.utils.ZipUtil;
import com.iot.product.sweeper.bean.Appointment;
import com.iot.product.sweeper.bean.AreaInfo;
import com.iot.product.sweeper.bean.CleanAreaInfo;
import com.iot.product.sweeper.bean.CleanRecord;
import com.iot.product.sweeper.bean.FirmwareUpdateInfo;
import com.iot.product.sweeper.bean.PathPoint;
import com.iot.product.sweeper.bean.Robot;
import com.iot.product.sweeper.bean.RobotStatus;
import com.iot.product.sweeper.bean.Room;
import com.iot.product.sweeper.bean.RoomCleanParam;
import com.iot.sdk.yugong.YuGongConstants;
import com.iot.sdk.yugong.YuGongError;
import com.iot.sdk.yugong.YuGongResponse;
import com.iot.sdk.yugong.YuGongSdk;
import com.iot.sdk.yugong.req.YuGongPayloadData;
import com.iot.sdk.yugong.req.YuGongPayloadDataList;
import com.iot.sdk.yugong.req.YuGongPayloadRemoveMultiMap;
import com.iot.sdk.yugong.req.YuGongPayloadSendUpgradeUrl;
import com.iot.sdk.yugong.req.YuGongPayloadSendVoiceBagUrl;
import com.iot.sdk.yugong.resp.DataListParam;
import com.iot.sdk.yugong.resp.YuGongRespData;
import com.iot.sdk.yugong.resp.YuGongRespDataCommon;
import com.iot.sdk.yugong.resp.YuGongRespDataList;
import com.iot.sweeper.AppContext;
import com.iot.sweeper.param.AddAppointmentParam;
import com.iot.sweeper.param.ChangeAppointmentParam;
import com.iot.sweeper.param.CleanSettingParam;
import com.iot.sweeper.param.ClearCustomModeParam;
import com.iot.sweeper.param.DeleteAppointmentParam;
import com.iot.sweeper.param.GetCleanRecordDetailParam;
import com.iot.sweeper.param.GetCleanRecordParam;
import com.iot.sweeper.param.MapNameParam;
import com.iot.sweeper.param.MergeRoomParam;
import com.iot.sweeper.param.MultiMapSwitchParam;
import com.iot.sweeper.param.RemoteControlParam;
import com.iot.sweeper.param.RemoveMapParam;
import com.iot.sweeper.param.RemoveMultiMapList;
import com.iot.sweeper.param.RenameMapParam;
import com.iot.sweeper.param.RenameRoomParam;
import com.iot.sweeper.param.ResetComsuptionParam;
import com.iot.sweeper.param.SaveCustomModeParam;
import com.iot.sweeper.param.SaveMapParam;
import com.iot.sweeper.param.SetAreaParam;
import com.iot.sweeper.param.SetMapParam;
import com.iot.sweeper.param.SetQuiteTimeParam;
import com.iot.sweeper.param.SplitRoomParam;
import com.iot.sweeper.product.YuGongDefaultSweeperProduct;
import com.yx.cloud.AppStatusConstant;
import com.yx.cloud.MyApplication;
import com.yx.cloud.R;
import com.yx.cloud.product.ProductConfigConstants;
import com.yx.cloud.product.laser.tuyapublic.ParseResult;
import com.yx.cloud.product.laser.tuyapublic.TuyaLaserConstant;
import com.yx.cloud.utils.PathUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Call;
import retrofit2.Callback;

public class X3_YXCLOUD extends YuGongDefaultSweeperProduct {
    public static final String PID = "spark-980";
    public static final String PNAME = "X3";
    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(50));
    private Gson gson = new Gson();

    protected X3_YXCLOUD() {
        getMap().setMap(new YxCloudLaserMap());
        getMap().setPath(new YxCloudLaserPath());
        setProductId(PID);
        getProduct().setProductName(PNAME);
        getProduct().setProductIcon(R.mipmap.robot_icon_pic_x3);
    }

    public static int getFanStringZw(int fan) {
        int fanStr = 0;
        switch (fan) {
            case 0:
                fanStr = 0;
                break;
            case 1:
                fanStr = 1;
                break;
            case 2:
                fanStr = 2;
                break;
            case 3:
                fanStr = 3;
                break;
            case 4:
                fanStr = 4;
                break;
        }
        return fanStr;
    }

    @Override
    public void setDeviceId(String deviceId) {
        super.setDeviceId(deviceId);
        try {
            //因为机器设置的风格图片是通过deviceid做key的  在创建对象初始化配置时还没有设置deviceid 所以在这里设置
            product.getConfigureMap().put(ProductConfigConstants.robot_Airview, X3CloudConfig.getRobotAirview(deviceId));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void parseDeviceData(Device device, Object data) {
        try {
            LogUtils.i("receive channel data:" + data);
            JSONObject dataJson;
            dataJson = new JSONObject((String) data);

            if (!dataJson.has(YuGongConstants.NOTIFY_INFO)) {
                if (!dataJson.has("func")) {//语言设置结果返回
                    return;
                } else {
                    Event.newBuilder().type(Event.MESSAGE_TYPE_DATA_FUNC).result(true).content(data).send();
                    return;
                }
            }
            String type = dataJson.getString(YuGongConstants.NOTIFY_INFO);

            if (type.equals(YuGongConstants.NOTIFY_TYPE_MAP)) {
                if (coundownIgnoreMapCount()) {
                    LogUtils.i("abandon map data : " + ignoreMapCount);
                    return;
                }
                String mapData = dataJson.getString(YuGongConstants.NOTIFY_TYPE_MAP);

                if (mapData == null) {
                    return;
                }

                byte[] compressed = Base64.decode(mapData, Base64.DEFAULT);//base64解密]
                if (compressed == null || compressed.length == 0) {
                    LogUtils.i("map data is null");
                    return;
                }
                byte[] bytes = ZipUtil.decompress(compressed);
                String mapDataUnzip = new String(bytes);
                JSONObject mapDataObject = new JSONObject(mapDataUnzip);
                String mapStr = null;
                if (mapDataObject.has("mapStr")) {
                    mapStr = mapDataObject.getString("mapStr");
                }
                if (mapStr == null) {
                    return;
                }

                byte[] byteData;
                byteData = StringUtils.hexToByte(mapStr);
                ParseResult mapResult = YxCloudMapDataParser.parseMapData((YxCloudLaserMap) (getMap().getMap()), (YxCloudLaserPath) (getMap().getPath()), getMap().getArea(), byteData);
                LogUtils.i("YxCloud map result is" + mapResult.getCode());
                if (mapResult.getCode() == com.yx.cloud.product.laser.tuyapublic.ParseResult.MSG_PARSE_SUCCESS) {
                    LogUtils.i("YxCloud map data refresh");
                    YxCloudLaserMap map = (YxCloudLaserMap) (getMap().getMap());
                    //充电座位置
                    getMap().getPower().setX(map.dockerPosX);
                    getMap().getPower().setY(map.dockerPosY);
                    LogUtils.i("YxCloud power location x ==  " + map.dockerPosX + "y == " + map.dockerPosY);
                    getMap().getPower().setRotation((float) map.dockertheta);
                    //机器位置
                    int endIndex = getMap().getPath().destPathPoints.size() - 1;
                    if (endIndex >= 0) {
                        PathPoint sweeperPoint = getMap().getPath().destPathPoints.get(endIndex);
                        float rotation = PathUtils.getRotationFromPath(getMap().getPath().destPathPoints);
                        getMap().getSweeper().set(sweeperPoint.x, sweeperPoint.y, rotation);
                    }

                    if (map.tempRoomData != null && map.tempRoomData.length > 0) {
                        YxCloudMapDataParser.parseRoomData((YxCloudLaserMap) (getMap().getMap()), getMap().getRoom(), map.tempRoomData);
                        if (map.roomsId != null && map.roomsId.size() > 0) {
                            for (int i = 0; i < map.room.size(); i++) {
                                for (int j = 0; j < getMap().getRoom().size(); j++) {
                                    if (map.room.get(i).getId() == getMap().getRoom().get(j).getId()) {
                                        getMap().getRoom().get(j).setCenter(map.room.get(i).getCenter());
                                    }
                                }
                            }
                        } else {
                            getMap().getRoom().clear();
                        }
                    } else {
                        getMap().getRoom().clear();
                    }
                    mapResult = YxCloudMapDataParser.parsePathData((YxCloudLaserMap) (getMap().getMap()), (YxCloudLaserPath) (getMap().getPath()), byteData);
                    Log.d("path refresh", "pathResult code is " + mapResult.getCode());
                    if (mapResult.getCode() == ParseResult.MSG_PARSE_SUCCESS) {
                        YxCloudLaserPath path = (YxCloudLaserPath) (getMap().getPath());
                        //机器位置
                        if (path.destPathPoints.size() > 0) {
                            PathPoint sweeperPoint = path.destPathPoints.get(path.destPathPoints.size() - 1);
                            float rotation = PathUtils.getRotationFromPath(getMap().getPath().destPathPoints);
                            getMap().getSweeper().set(sweeperPoint.x, sweeperPoint.y, rotation);
                        } else {
                            getMap().getSweeper().set(0, 0, 0);
                        }
                        Log.d("path refresh", "send MSG_ROBOT_PATH msg");
                        LogUtils.i("tuyapublic sweeper xy : " + getMap().getSweeper().x + " " + getMap().getSweeper().y);
                    } else if (mapResult.getCode() == ParseResult.MSG_PARSE_CLEAR_DATA) {
                        getMap().getPath().clear();
                        getMap().getSweeper().clear();
                    }
                    YxCloudMapDataParser.parseRecordForbidenLineData((YxCloudLaserMap) (getMap().getMap()), getMap().getArea(), byteData);
                    YxCloudMapDataParser.parseRecordForbidenAreaData((YxCloudLaserMap) (getMap().getMap()), getMap().getArea(), byteData);
                    YxCloudMapDataParser.parseRecordCleanAreaData((YxCloudLaserMap) (getMap().getMap()), getMap().getArea(), byteData);
                    int workMode = getRobotStatus().getWorkMode();
                    if (workMode != RobotStatus.MODE_CUSTOM_CLEAN) {
                        YxCloudMapDataParser.clearCleanArea(getMap().getArea());
                    }
                } else if (mapResult.getCode() == ParseResult.MSG_PARSE_FAIL_DATA_NOT_MATCH) {
                    LogUtils.i("YxCloud  map clear" + mapResult.getCode());
                    getMap().getRoom().clear();
                    getMap().getArea().clear();
                    getMap().getPath().clear();
                    getMap().getSweeper().clear();
                    getMap().getPower().clear();
                    getMap().getMap().mapData = null;
                }
                Event.newBuilder().type(Event.MSG_ROBOT_MAP).result(true).content(getMap().getMap()).send();
            } else if (type.equals(YuGongConstants.NOTIFY_TYPE_STATUS)) {
                parseDp(dataJson);
            } else if (type.equals(YuGongConstants.NOTIFY_TYPE_DEVICE_RESET)) {
                //设备重置
                LogUtils.i("重置 广播了。。。。。");
                boolean factory_reset = dataJson.getBoolean("factory_reset");
                if (!MyApplication.recvActive) {
                    Event.newBuilder().type(Event.MESSAGE_TYPE_DEVICE_RESET_LIST).result(true).content(factory_reset).send();
                } else {
                    Event.newBuilder().type(Event.MESSAGE_TYPE_DEVICE_RESET).result(true).content(factory_reset).send();
                }
            } else {
                //TODO 其他数据类型的解析
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void parseDp(JSONObject dataJson) throws JSONException {
        if (coundownIgnoreStateCount()) {
            LogUtils.i("abandon state data : " + ignoreStateCount);
            return;
        }

        JSONObject statusJson = dataJson.getJSONObject("thing_status");
        YxCloudLaserDataConverter.parseDp(this, statusJson);
    }


    @Override
    public void initConfig() {
        super.initConfig();
        //TODO 后续考虑从文件中读取
        X3CloudConfig.initConfig(getProduct().getConfigureMap(), this);
    }

    @Override
    public void startSweep(com.iot.sweeper.param.CleanParam param) {
        //根据类型判断是什么模式的开始清扫
        int cleanType = param.getType();
        if (cleanType == RobotStatus.MODE_AUTO_CLEAN) {
            //全局清扫
            sendToDevice(TuyaLaserConstant.SWITCH_GO, true);
        } else if (cleanType == RobotStatus.MODE_CUSTOM_CLEAN) {
            //划区清扫
            zoneClean(param);
        } else if (cleanType == RobotStatus.MODE_ROOM_CLEAN) {
            //选择房间
            roomClean(param);
        } else if (cleanType == RobotStatus.MODE_SPOT_CLEAN) {
            //局部清扫
            sendToDevice(TuyaLaserConstant.MODE, 3);
        }
    }

    @Override
    public void continueSweep(com.iot.sweeper.param.CleanParam param) {
        sendToDevice(TuyaLaserConstant.PAUSE, false);
    }

    @Override
    public void pauseSweep() {
        sendToDevice(TuyaLaserConstant.PAUSE, true);
    }

    @Override
    public void stopSweep() {
        sendToDevice(TuyaLaserConstant.SWITCH_GO, false);
    }

    @Override
    public void startRecharge() {
        sendToDevice(TuyaLaserConstant.SWITCH_CHARGE, true);
    }

    @Override
    public void pauseRecharge() {
        sendToDevice(TuyaLaserConstant.PAUSE, true);
    }

    @Override
    public void continueRecharge() {
        sendToDevice(TuyaLaserConstant.PAUSE, false);
    }

    @Override
    public void stopRecharge() {
        sendToDevice(TuyaLaserConstant.SWITCH_CHARGE, false);
    }

    @Override
    public void saveMap(SaveMapParam param) {
        List<Byte> bytes = new ArrayList<>();
        bytes.add((byte) (0x01));

        byte[] sumData;
        byte[] data;

        if (bytes.size() > 0) {
            sumData = new byte[bytes.size()];

            for (int i = 0; i < bytes.size(); i++) {
                sumData[i] = bytes.get(i);
            }

            data = getProtocolPackage1((byte) 0x2A, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }
    }

    @Override
    public void resetMap() {
        sendToDevice(TuyaLaserConstant.RESET_MAP, true);
    }

    @Override
    public void setCurrentMap(SetMapParam param) {
        List<Byte> bytes = new ArrayList<>();

        //int extendId = Integer.parseInt(param.getExtend().split("_")[2]);
        byte[] mapIdBytes = StringUtils.intToByteArray(param.getMapId());
        for (int i = 0; i < mapIdBytes.length; i++) {
            bytes.add(mapIdBytes[i]);
        }

        byte[] urlLen = null;
        byte[] urlBytes = null;
        try {
            urlBytes = param.getUrl().getBytes("utf-8");
            String name = new String(urlBytes, "utf-8");
            Log.d("ZW", "url is " + name);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (urlBytes != null && urlBytes.length > 0) {
            urlLen = StringUtils.intToByteArray(urlBytes.length);
        }

        for (int i = 0; i < urlLen.length; i++) {
            bytes.add(urlLen[i]);
        }

        for (int i = 0; i < urlBytes.length; i++) {
            bytes.add(urlBytes[i]);
        }

        byte[] sumData;
        byte[] data;

        if (bytes.size() > 0) {
            sumData = new byte[bytes.size()];

            for (int i = 0; i < bytes.size(); i++) {
                sumData[i] = bytes.get(i);
            }

            data = getProtocolPackage1((byte) 0x2E, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }
    }

    @Override
    public void removeMap(RemoveMapParam param) {
        //删除本地地图
        byte[] sumData = StringUtils.intToByteArray(param.getMapId());
        byte[] data;
        if (sumData.length > 0) {
            data = getProtocolPackage1((byte) 0x2C, sumData);
            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }
        //删除云端地图
        DataParam dataParam = new DataParam();
        dataParam.setData_type("reuse_map");
        dataParam.setFile_name(param.getFileName());
        deleteData(dataParam);
    }

    /**
     * 多地图关闭，主动删除云端地图
     */
    @Override
    public void removeMultiMapList(RemoveMultiMapList param) {
        //删除云端地图
        DataListParam dataListParam = new DataListParam();
        dataListParam.setData_type("reuse_map");
        dataListParam.setFile_names(param.getFileNames());
        deleteDataList(dataListParam);
    }


    @Override
    public void renameMap(RenameMapParam param) {
        //修改描述文件
    }

    @Override
    public void sendAliveHeartbeat() {
        sendToDevice(TuyaLaserConstant.REQUEST, 1);
    }

    public void zoneClean(com.iot.sweeper.param.CleanParam param) {
        Robot robot = AppContext.get().getCurrentDevice();
        //区域
        List<Byte> areaBytes = new ArrayList<>();
        int areaCount = 0;
        areaBytes.add((byte) 0x00);
        areaBytes.add((byte) 0x00);

        for (com.iot.sweeper.param.CleanParam.SweepParam sweepParam : param.getSweepParamList()) {
            com.iot.sweeper.param.CleanParam.AreaSweepParam areaSweepParam = (com.iot.sweeper.param.CleanParam.AreaSweepParam) sweepParam;
            CleanAreaInfo areaInfo = (CleanAreaInfo) areaSweepParam.getArea();
            if (areaInfo.getType() != AreaInfo.TYPE_CLEAN) {
                continue;
            }

            areaBytes.set(0, (byte) (areaInfo.getCleanTimes() & 0xff));
            Log.d("nnn", "set clean times is " + areaInfo.getCleanTimes());
            areaBytes.set(1, (byte) ++areaCount);
            List<Double> points = areaInfo.getBorder();
            areaBytes.add((byte) (points.size() / 2));
            for (int i = 0; i < points.size() / 2; i++) {
                double x = points.get(i * 2);
                double y = points.get(i * 2 + 1);
                PointF pointF = new PointF((float) x, (float) y);
                ArrayList<Short> point = YxCloudMapDataParser.getWorldPoint(pointF, (YxCloudLaserMap) robot.getMap().getMap());
                byte[] byte1x = StringUtils.convertShortToTwoBytes(point.get(0));
                byte[] byte1y = StringUtils.convertShortToTwoBytes(point.get(1));
                areaBytes.add(byte1x[0]);
                areaBytes.add(byte1x[1]);
                areaBytes.add(byte1y[0]);
                areaBytes.add(byte1y[1]);
            }
        }

        byte[] sumData;
        byte[] data;

        if (areaBytes.size() > 0) {
            sumData = new byte[areaBytes.size()];

            for (int i = 0; i < areaBytes.size(); i++) {
                sumData[i] = areaBytes.get(i);
            }

            data = getProtocolPackage((byte) 0x28, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }
    }

    private void roomClean(com.iot.sweeper.param.CleanParam param) {
        //设置房间清扫顺序
        List<Byte> roomOrder = new ArrayList<>();
        List<com.iot.sweeper.param.CleanParam.SweepParam> sweepParamList = param.getSweepParamList();
        int len = sweepParamList.size();
        Log.d("selectedRoom", "selectedRoom size is" + len);
        roomOrder.add((byte) (len & 0xff));

        byte cleanTimes;
        com.iot.sweeper.param.CleanParam.RoomSweepParam sweepParam = ((com.iot.sweeper.param.CleanParam.RoomSweepParam) sweepParamList.get(0));
        cleanTimes = (byte) (sweepParam.cleanSettings.getCleanTimes() & 0xff);

        for (int i = 0; i < sweepParamList.size(); i++) {
            com.iot.sweeper.param.CleanParam.RoomSweepParam roomSweepParam = ((com.iot.sweeper.param.CleanParam.RoomSweepParam) sweepParamList.get(i));
            roomOrder.add((byte) ((roomSweepParam.room.getId()) & 0xff));
        }

        byte[] sumData;
        byte[] data;

        //区域清扫
        List<Byte> areaBytes = new ArrayList<>();
        areaBytes.add(cleanTimes);
        areaBytes.add((byte) (roomOrder.size() - 1));
        for (int i = 1; i < roomOrder.size(); i++) {
            areaBytes.add(roomOrder.get(i));
        }

        if (areaBytes.size() > 0) {
            sumData = new byte[areaBytes.size()];

            for (int i = 0; i < areaBytes.size(); i++) {
                sumData[i] = areaBytes.get(i);
            }

            data = getProtocolPackage((byte) 0x14, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }

    }

    @Override
    public void renameRoom(RenameRoomParam param) {
        List<Byte> bytes = new ArrayList<>();

        byte[] nameBytes = null;
        int nameLen = 0;
        try {
            nameBytes = param.name.getBytes("utf-8");
            String name = new String(nameBytes, "utf-8");
            Log.d("ZW", "room name is " + name);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (nameBytes != null && nameBytes.length > 0 && nameBytes.length <= 19) {
            nameLen = nameBytes.length;
        } else if (nameBytes.length > 19) {
            nameLen = 19;
        }

        //data
        bytes.add((byte) (1));
        bytes.add((byte) (param.roomId));
        bytes.add((byte) nameLen);

        for (int i = 0; i < nameLen; i++) {
            bytes.add(nameBytes[i]);
        }
        for (int i = 0; i < 19 - nameLen; i++) {
            bytes.add((byte) 0x00);
        }

        byte[] sumData = new byte[bytes.size()];

        for (int i = 0; i < bytes.size(); i++) {
            sumData[i] = bytes.get(i);
        }

        byte[] data = getProtocolPackage((byte) 0x24, sumData);

        sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
    }

    @Override
    public void splitRoom(SplitRoomParam param) {
        Robot robot = AppContext.get().getCurrentDevice();
        YxCloudLaserMap map = (YxCloudLaserMap) robot.getMap().getMap();

        List<Byte> bytes = new ArrayList<>();
        bytes.add((byte) (param.roomId));

        //第一个点
        ArrayList<Short> point1 = YxCloudMapDataParser.getWorldPoint(param.point1, map);
        short point1x = point1.get(0);
        short point1y = point1.get(1);
        byte[] byte1x = StringUtils.convertShortToTwoBytes(point1x);
        byte[] byte1y = StringUtils.convertShortToTwoBytes(point1y);
        bytes.add(byte1x[0]);
        bytes.add(byte1x[1]);
        bytes.add(byte1y[0]);
        bytes.add(byte1y[1]);

        //第二个点
        ArrayList<Short> point2 = YxCloudMapDataParser.getWorldPoint(param.point2, map);
        short point2x = point2.get(0);
        short point2y = point2.get(1);
        byte[] byte2x = StringUtils.convertShortToTwoBytes(point2x);
        byte[] byte2y = StringUtils.convertShortToTwoBytes(point2y);
        bytes.add(byte2x[0]);
        bytes.add(byte2x[1]);
        bytes.add(byte2y[0]);
        bytes.add(byte2y[1]);

        byte[] sumData = new byte[bytes.size()];
        for (int i = 0; i < bytes.size(); i++) {
            sumData[i] = bytes.get(i);
        }

        byte[] data = getProtocolPackage((byte) 0x1C, sumData);

        sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
    }

    @Override
    public void mergeRoom(MergeRoomParam param) {
        List<Byte> bytes = new ArrayList<>();
        bytes.add((byte) (param.room1));
        bytes.add((byte) (param.room2));
        byte[] sumData = new byte[bytes.size()];
        for (int i = 0; i < bytes.size(); i++) {
            sumData[i] = bytes.get(i);
        }

        byte[] data = getProtocolPackage((byte) 0x1E, sumData);

        sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
    }

    @Override
    public void clearCustomMode(ClearCustomModeParam param) {
        List<byte[]> dataList = new ArrayList<>();
        for (Room room : param.getRoomList()) {
            byte[] data = new byte[5];
            data[0] = (byte) (room.getId() & 0xff);
            data[1] = (byte) 0xff;
            data[2] = (byte) 0xff;
            data[3] = (byte) 0xff;
            data[4] = (byte) 0x01;
            dataList.add(data);
        }

        int roomDataLen = dataList.size() * 5;
        byte[] roomData = new byte[roomDataLen];
        for (int i = 0; i < dataList.size(); i++) {
            System.arraycopy(dataList.get(i), 0, roomData, i * 5, dataList.get(i).length);
        }

        byte[] sumData = new byte[roomDataLen + 1];
        sumData[0] = (byte) param.getRoomList().size();
        System.arraycopy(roomData, 0, sumData, 1, roomData.length);

        byte[] data = getProtocolPackage((byte) 0x22, sumData);

        sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
    }

    @Override
    public void saveCustomMode(SaveCustomModeParam param) {
        List<byte[]> dataList = new ArrayList<>();
        for (Room room : param.getRoomList()) {
            byte[] data = new byte[5];
            data[0] = (byte) (room.getId() & 0xff);
            data[1] = (byte) (room.getSuction() & 0xff);
            data[2] = (byte) (room.getHumidity() & 0xff);
            data[3] = (byte) 0xff;
            data[4] = (byte) (room.getCleanTimes() & 0xff);
            dataList.add(data);
        }

        int roomDataLen = dataList.size() * 5;
        byte[] roomData = new byte[roomDataLen];
        for (int i = 0; i < dataList.size(); i++) {
            System.arraycopy(dataList.get(i), 0, roomData, i * 5, dataList.get(i).length);
        }

        byte[] sumData = new byte[roomDataLen + 1];
        sumData[0] = (byte) param.getRoomList().size();
        System.arraycopy(roomData, 0, sumData, 1, roomData.length);

        byte[] data = getProtocolPackage((byte) 0x22, sumData);

        sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
    }


    @Override
    public void setArea(SetAreaParam param) {
        Robot robot = AppContext.get().getCurrentDevice();
        //虚拟墙设置 / 禁区设置（禁过、禁拖）
        List<Byte> lineBytes = new ArrayList<>();
        List<Byte> areaBytes = new ArrayList<>();
        int lineCount = 0;
        int areaCount = 0;
        lineBytes.add((byte) 0x00);
        areaBytes.add((byte) 0x00);
        for (AreaInfo areaInfo : param.getAreaList()) {
            if (areaInfo.getType() == AreaInfo.TYPE_CLEAN) {
                continue;
            }

            if (areaInfo.getType() == AreaInfo.TYPE_FORBIDDEN_LINE) {
                lineBytes.set(0, (byte) ++lineCount);
                List<Double> points = areaInfo.getBorder();
                for (int i = 0; i < points.size() / 2; i++) {
                    double x = points.get(i * 2);
                    double y = points.get(i * 2 + 1);
                    PointF pointF = new PointF((float) x, (float) y);
                    ArrayList<Short> point = YxCloudMapDataParser.getWorldPoint(pointF, (YxCloudLaserMap) robot.getMap().getMap());
                    byte[] byte1x = StringUtils.convertShortToTwoBytes(point.get(0));
                    byte[] byte1y = StringUtils.convertShortToTwoBytes(point.get(1));
                    lineBytes.add(byte1x[0]);
                    lineBytes.add(byte1x[1]);
                    lineBytes.add(byte1y[0]);
                    lineBytes.add(byte1y[1]);
                }
            }

            if (areaInfo.getType() == AreaInfo.TYPE_FORBIDDEN_MOP || areaInfo.getType() == AreaInfo.TYPE_FORBIDDEN) {
                areaBytes.set(0, (byte) ++areaCount);
                if (areaInfo.getType() == AreaInfo.TYPE_FORBIDDEN_MOP) {
                    areaBytes.add((byte) 0x02);
                } else if (areaInfo.getType() == AreaInfo.TYPE_FORBIDDEN) {
                    areaBytes.add((byte) 0x00);
                }
                List<Double> points = areaInfo.getBorder();
                areaBytes.add((byte) (points.size() / 2));
                for (int i = 0; i < points.size() / 2; i++) {
                    double x = points.get(i * 2);
                    double y = points.get(i * 2 + 1);
                    PointF pointF = new PointF((float) x, (float) y);
                    ArrayList<Short> point = YxCloudMapDataParser.getWorldPoint(pointF, (YxCloudLaserMap) robot.getMap().getMap());
                    byte[] byte1x = StringUtils.convertShortToTwoBytes(point.get(0));
                    byte[] byte1y = StringUtils.convertShortToTwoBytes(point.get(1));
                    areaBytes.add(byte1x[0]);
                    areaBytes.add(byte1x[1]);
                    areaBytes.add(byte1y[0]);
                    areaBytes.add(byte1y[1]);
                }
            }
        }

        byte[] sumData;
        byte[] data;

        if (lineBytes.size() > 0) {
            sumData = new byte[lineBytes.size()];

            for (int i = 0; i < lineBytes.size(); i++) {
                sumData[i] = lineBytes.get(i);
            }

            data = getProtocolPackage((byte) 0x12, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }

        if (areaBytes.size() > 0) {
            sumData = new byte[areaBytes.size()];

            for (int i = 0; i < areaBytes.size(); i++) {
                sumData[i] = areaBytes.get(i);
            }

            data = getProtocolPackage((byte) 0x1A, sumData);

            sendToDevice(TuyaLaserConstant.COMMAND_TRANS, StringUtils.byte2hex(data));
        }

    }

    /**
     * 设置勿扰模式开关、时间
     *
     * @return
     */
    @Override
    public void setQuiteTimeSettings(SetQuiteTimeParam param) {
        //设置勿扰模式开关
        if (param.hasSetSwitch()) {
            sendToDevice(TuyaLaserConstant.SWITCH_DISTURB, param.ismSwitch());
        }

        if (param.hasSetTime()) {
            int startHour = param.getStartHour();
            int startMin = param.getStartMin();
            int endHour = param.getEndHour();
            int endMin = param.getEndMin();
            int timeZone = TimeZone.getDefault().getRawOffset() / 3600000;

            List<Byte> bytes = new ArrayList<>();
            bytes.add((byte) (timeZone & 0xff));
            bytes.add((byte) (startHour & 0xff));
            bytes.add((byte) (startMin & 0xff));
            bytes.add((byte) (0x00));
            bytes.add((byte) (endHour & 0xff));
            bytes.add((byte) (endMin & 0xff));
            bytes.add((byte) (0x00));

            byte[] sumData;
            byte[] data;

            if (bytes.size() > 0) {
                sumData = new byte[bytes.size()];

                for (int i = 0; i < bytes.size(); i++) {
                    sumData[i] = bytes.get(i);
                }

                data = getProtocolPackage((byte) 0x32, sumData);

                sendToDevice("33", StringUtils.byte2hex(data));
            }
        }
    }

    @Override
    public void getCleanRecordStatistics() {

    }

    @Override
    public void sendUpgradeUrlToDevice(DataBag dataBag) {
        YuGongPayloadSendUpgradeUrl payload = YuGongPayloadSendUpgradeUrl
                .newBuilder(YuGongConstants.OPT_DEVICE_CONTROL)
                .thing_name(getDeviceId())
                .dataBag(dataBag)
                .build();
        LogUtils.i("  发消息给设备 数据   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().sendUpgradeUrlToDevice(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("发消息给设备 数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespDataCommon data = result.getData();
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(true).content(data).send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void sendVoiceBagUrlToDevice(DataBag dataBag) {
        YuGongPayloadSendVoiceBagUrl payload = YuGongPayloadSendVoiceBagUrl
                .newBuilder(YuGongConstants.OPT_DEVICE_CONTROL)
                .thing_name(getDeviceId())
                .dataBag(dataBag)
                .build();
        LogUtils.i("  发消息给设备 数据   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().sendVoiceBagUrlToDevice(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataCommon>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataCommon>> call, retrofit2.Response<YuGongResponse<YuGongRespDataCommon>> response) {
                YuGongResponse<YuGongRespDataCommon> result = response.body();
                LogUtils.i("发消息给设备 数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespDataCommon data = result.getData();
                    //TODO 解析数据
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(true).content(data).send();
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_MESSAGE_DEVICE).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataCommon>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }


    @Override
    public void getMapList() {
        DataParam dataParam = new DataParam();
        dataParam.setData_type("reuse_map");
        getDataList(dataParam);
    }

    @Override
    public void getMapListDetail(List<CleanRecord> cleanRecords) {
        GetCloudFileRunnable getCloudFileRunnable = new GetCloudFileRunnable(cleanRecords, Event.MESSAGE_TYPE_GET_MULTI_MAP);
        threadPoolExecutor.execute(getCloudFileRunnable);
    }

    @Override
    public void saveMapListNames(List<MapNameParam> params) {
        //保存本地地图name列表
        List<Byte> bytes = new ArrayList<>();
        for (MapNameParam mapNameParam : params) {
            byte[] nameBytes = null;
            int nameLen = 0;
            try {
                nameBytes = mapNameParam.getMapName().getBytes("utf-8");
                String name = new String(nameBytes, "utf-8");
                Log.d("ZW", "room name is " + name);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (nameBytes != null && nameBytes.length > 0 && nameBytes.length <= 19) {
                nameLen = nameBytes.length;
            } else if (nameBytes.length > 19) {
                nameLen = 19;
            }

            bytes.add((byte) (mapNameParam.getMapId()));
            bytes.add((byte) nameLen);

            for (int i = 0; i < nameLen; i++) {
                bytes.add(nameBytes[i]);
            }
            for (int i = 0; i < 19 - nameLen; i++) {
                bytes.add((byte) 0x00);
            }
        }

        int nameDataLen = bytes.size();
        byte[] sumData = new byte[nameDataLen + 1];
        sumData[0] = (byte) params.size();
        for (int i = 0; i < bytes.size(); i++) {
            sumData[i + 1] = bytes.get(i);
        }

        byte[] data;
        if (sumData.length > 0) {
            data = getProtocolPackage1((byte) 0x53, sumData);
            sendToDevice(TuyaLaserConstant.MAP_MAP_NAME_LIST, StringUtils.byte2hex(data));
        }
    }

    public void getMultiMapDetail(List<CleanRecord> multiMapDetails) {
        GetMultiMapDetailList getMultiMapDetailList = new GetMultiMapDetailList(multiMapDetails);
        getMultiMapDetailList.start();
    }

    /**
     * 说明 ：| 字段名称 | 数据类型 | 必须 | 字段描述 |
     * | --- | --- | --- | --- |
     * | data_type | String | 是 | 获取数据的类型 |
     * | thing_name | String | 是 | 获取数据的指定设备名称 |
     * | mac | String | 是 | 获取数据的指定设备mac地址 （格式：中间是 -（破折号），不是：（冒号），字母全部转小写） |
     * | resource_list | List | 是 | 所有文件夹列表 |
     * | file_name | String | 是 | 文件夹名 |
     * | describe_file | Dict | 是 | 对应文件夹中描述文件所有内容 |
     */
    public void getDataList(DataParam param) {
        YuGongPayloadDataList payload = YuGongPayloadDataList
                .newBuilder(YuGongConstants.OPT_RESOURCE_LIST_GET)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  : 数据列表 ww  :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().getDataList(payload).enqueue(new Callback<YuGongResponse<YuGongRespDataList>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespDataList>> call, retrofit2.Response<YuGongResponse<YuGongRespDataList>> response) {
                YuGongResponse<YuGongRespDataList> result = response.body();
                LogUtils.i("数据列表 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespDataList data = result.getData();
                    if (param.getData_type().equals("voice_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(true).content(data).send();
                    } else if (param.getData_type().equals("clean_record")) {
                        List<CleanRecord> recordList = new ArrayList<>();
                        recordList.clear();
                        List<YuGongRespDataList.ResourceListBean> resource_list = data.getResource_list();
                        for (int i = resource_list.size() - 1; i >= 0; i--) {
                            YuGongRespDataList.ResourceListBean resourceListBean = resource_list.get(i);
                            String[] fileName = resourceListBean.getFile_name().split("_");
                            String date = fileName[1].substring(0, 4) + "-" + fileName[1].substring(4, 6) + "-" + fileName[1].substring(6, 8);
                            String time = fileName[2].substring(0, 2) + ":" + fileName[2].substring(2, 4) + ":" + fileName[2].substring(4, 6);
                            String startTime = date + "  " + time;
                            int cleanTime = Integer.valueOf(fileName[3]);
                            int cleanArea = Integer.valueOf(fileName[4]);
                            CleanRecord cleanRecordAdapterBean = new CleanRecord();
                            cleanRecordAdapterBean.setStartTime(startTime);
                            cleanRecordAdapterBean.setCleanTime(cleanTime);
                            cleanRecordAdapterBean.setArea(cleanArea);
                            cleanRecordAdapterBean.setIsDoneNormal(1);
                            cleanRecordAdapterBean.setFileName(resourceListBean.getFile_name());
                            recordList.add(cleanRecordAdapterBean);
                        }
                        Event.newBuilder().type(Event.MESSAGE_TYPE_GET_CLEAN_RECORD).result(true).content(recordList).send();
                    } else if (param.getData_type().equals("reuse_map")) {
                        List<CleanRecord> recordList = new ArrayList<>();
                        List<YuGongRespDataList.ResourceListBean> resource_list = data.getResource_list();
                        for (int i = 0; i < resource_list.size(); i++) {
                            YuGongRespDataList.ResourceListBean resourceListBean = resource_list.get(i);
                            String describeFile = resourceListBean.getDescribe_file();
                            try {
                                JSONObject describeFileObject = new JSONObject(describeFile);
                                if (describeFileObject.has("MapID")) {
                                    CleanRecord cleanRecordAdapterBean = new CleanRecord();
                                    int mapId = describeFileObject.getInt("MapID");
                                    cleanRecordAdapterBean.setId(String.valueOf(mapId));
                                    if (describeFileObject.has("name")) {
                                        String mapName = describeFileObject.getString("name");
                                        cleanRecordAdapterBean.setName(mapName);
                                    }
                                    cleanRecordAdapterBean.setFileName(resourceListBean.getFile_name());
                                    recordList.add(cleanRecordAdapterBean);
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                        getMultiMapDetail(recordList);
                    } else if (param.getData_type().equals("upgrade_package")) {
                        List<YuGongRespDataList.ResourceListBean> resource_list = data.getResource_list();
                        LogUtils.i("upgrade_package " + new Gson().toJson(resource_list));
                        //“notify”表示提醒升级，”detect”表示检测升级， “force”表示强制升级，”silent”表示静默升级
                        if (resource_list.size() > 0) {
                            String push_type = resource_list.get(0).getPush_type();
                            LogUtils.i("固件升级的状态 ： " + push_type);

                            YuGongRespDataList.ResourceListBean resourceListBean = resource_list.get(0);
                            String describeFile = resourceListBean.getDescribe_file();
                            String fileName = resourceListBean.getFile_name();
                            FirmwareUpdateInfo firmwareUpdateInfo = new FirmwareUpdateInfo();
                            firmwareUpdateInfo.setFileName(fileName);
                            firmwareUpdateInfo.setDesc(describeFile);
                            firmwareUpdateInfo.setUpgradeStatus(1);
                            firmwareUpdateInfo.setState(1);
                            firmwareUpdateInfo.setNewVersion(describeFile);
                            Event.newBuilder().type(Event.MESSAGE_TYPE_CHECK_NEW_VERSION).result(true).content(firmwareUpdateInfo).send();
                        } else {
                            Event.newBuilder().type(Event.MESSAGE_TYPE_CHECK_NEW_VERSION).result(false).send();
                        }
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_VOICE_LIST).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespDataList>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                LogUtils.i("数据列表 失败 :" + errorInfo);
            }
        });
    }

    public void getData(DataParam param) {
        YuGongPayloadData payload = YuGongPayloadData
                .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_GET)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .file_name(param.getFile_name())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  : 获取数据 nn   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().getData(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                YuGongResponse<YuGongRespData> result = response.body();
                LogUtils.i("获取数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    YuGongRespData data = result.getData();
                    if (param.getData_type().equals("voice_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(true).content(data).send();
                    } else if (param.getData_type().equals("clean_record")) {
                        List<YuGongRespData.FileListBean> listBeans = data.getFile_list();
                        List<CleanRecord> cleanRecords = new ArrayList<>();
                        CleanRecord cleanRecord = new CleanRecord();
                        cleanRecord.setUrl(listBeans.get(0).getData_s3_url());
                        cleanRecords.add(cleanRecord);
                        GetCloudFileRunnable getCloudFileRunnable = new GetCloudFileRunnable(cleanRecords, Event.MESSAGE_TYPE_GET_CLEAN_RECORD_DETAIL);
                        threadPoolExecutor.execute(getCloudFileRunnable);
                    } else if (param.getData_type().equals("upgrade_package")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_SEND_UPGRADE_URL_TO_DEVICE).result(true).content(data).send();
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    public void deleteData(DataParam param) {
        YuGongPayloadData payload = YuGongPayloadData
                .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_DELETE)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .file_name(param.getFile_name())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  : 删除数据 nn   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().deleteData(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                YuGongResponse<YuGongRespData> result = response.body();
                LogUtils.i("删除数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    if (param.getData_type().equals("reuse_map")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_DELETE_MULTI_MAP).result(true).content(null).send();
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    public void deleteDataList(DataListParam param) {
        YuGongPayloadRemoveMultiMap payload = YuGongPayloadRemoveMultiMap
                .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_BATCH_DELETE)
                .thing_name(getDeviceId())
                .data_type(param.getData_type())
                .file_list(param.getFile_names())
                .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                .build();
        LogUtils.i("  : 删除数据 nn   :" + gson.toJson(payload));
        YuGongSdk.get().getWebService().deleteDataList(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
            @Override
            public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                YuGongResponse<YuGongRespData> result = response.body();
                LogUtils.i("删除数据 :" + gson.toJson(result));
                if (result == null) {
                    String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                    return;
                }
                if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                    if (param.getData_type().equals("reuse_map")) {
                        Event.newBuilder().type(Event.MESSAGE_TYPE_DELETE_MULTI_MAP).result(true).content(null).send();
                    }
                } else {
                    String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                    Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                }
            }

            @Override
            public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
            }
        });
    }

    @Override
    public void multiMapSwitch(MultiMapSwitchParam param) {
        sendToDevice(TuyaLaserConstant.MULTI_MAP_SWITCH, param.isOpen());
    }

    @Override
    public void getCleanRecord(GetCleanRecordParam param) {
        DataParam dataParam = new DataParam();
        dataParam.setData_type("clean_record");
        getDataList(dataParam);
    }

    @Override
    public void getCleanRecordDetail(GetCleanRecordDetailParam param) {
        DataParam dataParam = new DataParam();
        dataParam.setData_type("clean_record");
        dataParam.setFile_name(param.getCleanRecord().getFileName());
        getData(dataParam);
    }

    @Override
    public void setDeviceCleanSettings(CleanSettingParam param) {
        LogUtils.i("setCleanSettings ---------------------------yyy ");

        HashMap<String, Object> hashMap = null;
        //音量
        if (param.hasset_volume) {
            sendToDevice(TuyaLaserConstant.VOLUME_SET, param.getVolume());
        }
        //吸力
        if (param.hasset_suction) {
//            int fanString = getFanStringZw(param.getSuction());
            sendToDevice(TuyaLaserConstant.SUCTION, param.getSuction());
        }

        //水量
        if (param.hasset_mopHumidity) {
//            String waterString = getWaterStringZw(param.getBaseWater());
            sendToDevice(TuyaLaserConstant.CISTERN, param.getMopHumidity());
        }

        //地毯增压
        if (param.hasset_carpetPressurize) {
            sendToDevice(TuyaLaserConstant.AUTO_BOOST, param.isCarpetPressurize());
        }

        //Y字清扫 精擦
        if (param.hasset_fineBrush) {
            sendToDevice(TuyaLaserConstant.Y_MOP, param.isFineBrush());
        }
        //自动集尘开关
        if (param.hasset_autoDust) {
            sendToDevice(TuyaLaserConstant.DUST_COLLECTION_SWITCH, param.isAutoDust());
        }

        //自动集尘频率
        if (param.hasset_autoDust_frequency) {
            sendToDevice(TuyaLaserConstant.DUST_COLLECTION_NUM, param.getAutoDustFrequency());
        }
        //断点续扫
        if (param.hasset_breakpointResume) {
            sendToDevice(TuyaLaserConstant.BREAK_CLEAN, param.isBreakpointResume());
        }
        //定制模式
        if (param.hasset_customSwitch) {
            sendToDevice(TuyaLaserConstant.CUSTOM_MODE_SWITCH, param.isCustomSwitch());
        }
        //天猫精灵设备id
        if (param.hasset_tmallDrviceId) {
            String tmallDrviceId = param.getTmallDrviceId();
//            hashMap.clear();
//            hashMap.put(TuyaLaserConstant.TMALL_DRVICE_ID, tmallDrviceId);
//            TuyaSdk.get().publishDps(com.alibaba.fastjson.JSONObject.toJSONString(hashMap));
            sendToDevice(TuyaLaserConstant.TMALL_DRVICE_ID, tmallDrviceId);
        }
    }

    public void sendTimeZoneToDevice() {
        String displayName = TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT);
        LogUtils.i(" : 系统时区 222  ：" + displayName);
        String[] split = displayName.split("\\+");
        String[] splitxxx = split[1].split(":");
        LogUtils.i(" : 系统时区 33  ：" + Integer.parseInt(splitxxx[0]));
        sendToDevice(TuyaLaserConstant.TIME_ZONE, Integer.parseInt(splitxxx[0]));
    }

    public void sendToDevice(String key, Object value) {
        LogUtils.i("sendToDevice : " + key + " - " + value);
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("opt", YuGongConstants.OPT_SEND_MESSAGE_TO_DEVICE);
            jsonObject.put("thing_name", getDeviceId());
            jsonObject.put("sub_type", getProductId());
            jsonObject.put(key, value);
            YuGongSdk.get().sendCmd(jsonObject);
            LogUtils.i("sendToDevice : " + jsonObject.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
        AppStatusConstant.ignoreStateCount = 1;

    }

    @Override
    public void getAppointment() {
        List<Appointment> list = getAppointmentList();
        Log.d("getAppointmentList", "mList is " + new Gson().toJson(list));
        Event.newBuilder().type(Event.MESSAGE_TYPE_QUERY_ALARM).result(true).content(list).send();
    }

    @Override
    public void addAppointment(AddAppointmentParam param) {
        List<Appointment> addAppointmentList = new ArrayList<>(getAppointmentList());
        addAppointmentList.add(param.getAppointment());
        constructAppointment(addAppointmentList);
    }

    @Override
    public void changeAppointment(ChangeAppointmentParam param) {
        List<Appointment> appointmentList = new ArrayList<>(getAppointmentList());

        for (int i = 0; i < appointmentList.size(); i++) {
            if (appointmentList.get(i).getId() == param.getAppointment().getId()) {
                appointmentList.set(i, param.getAppointment());
                break;
            }
        }
        constructAppointment(appointmentList);
    }

    @Override
    public void deleteAppointment(DeleteAppointmentParam param) {
        List<Appointment> appointmentList = new ArrayList<>(getAppointmentList());
        for (int i = 0; i < appointmentList.size(); i++) {
            if (appointmentList.get(i).getId() == param.getAppointment().getId()) {
                appointmentList.remove(i);
                break;
            }
        }
        constructAppointment(appointmentList);
    }

    @Override
    public void switchAppointment(ChangeAppointmentParam param) {
        changeAppointment(param);
    }

    private void constructAppointment(List<Appointment> appointmentList) {
        List<Byte> bytes = new ArrayList<>();
        if (appointmentList.size() >= 0) {
            int timeZone = TimeZone.getDefault().getRawOffset() / 3600000;
            int appointmentNum = appointmentList.size();
            bytes.add((byte) (timeZone & 0xff));
            bytes.add((byte) (appointmentNum & 0xff));
            for (int i = 0; i < appointmentNum; i++) {
                Appointment appointment = appointmentList.get(i);
                if (appointment.isEnable()) {
                    bytes.add((byte) (0x01));
                } else {
                    bytes.add((byte) (0x00));
                }

                List<Integer> repeat = appointment.getRepeat();
                if (repeat.size() > 0) {
                    byte repeatByte = 0;
                    for (Integer integer : repeat) {
                        if (integer == 0) {
                            repeatByte |= (byte) 0x01 << 6;
                        } else {
                            repeatByte |= (byte) 0x01 << (integer - 1);
                        }

                    }
                    Log.d("repeat", "repeat is " + StringUtils.byteToBit(repeatByte));
                    bytes.add(repeatByte);
                } else {
                    bytes.add((byte) (0x00));
                }

                int startHour = appointment.getTime() / 3600;
                int startMin = appointment.getTime() % 3600 / 60;
                bytes.add((byte) (startHour & 0xff));
                bytes.add((byte) (startMin & 0xff));

                com.iot.product.sweeper.bean.CleanParam cleanParam = appointment.getCleanParam();
                int cleanMode = appointment.getCleanMode();
                List<Integer> roomIds = null;
                if (cleanMode == 1) {
                    roomIds = ((RoomCleanParam) cleanParam).getRoomIds();
                }
                if (roomIds == null || roomIds.size() == 0) {
                    bytes.add((byte) (0x00));
                    int suction = appointment.getCleanParam().suction;
                    int humidity = appointment.getCleanParam().humidity;
                    int cleanType = 0;
                    if (suction == 0 && humidity != 0) {
                        cleanType = 2;
                    } else if (suction != 0 && humidity == 0) {
                        cleanType = 1;
                    } else if (suction != 0 & humidity != 0) {
                        cleanType = 0;
                    }

                    bytes.add((byte) (cleanType & 0xff));
                    bytes.add((byte) (suction & 0xff));
                    bytes.add((byte) (humidity & 0xff));

                    //清扫次数，默认为1次
                    int cleanTimes = 1;
                    bytes.add((byte) (cleanTimes & 0xff));
                } else {
                    bytes.add((byte) (roomIds.size() & 0xff));
                    for (int roomId : roomIds) {
                        Log.d("roomId", "roomId is " + roomId);
                        bytes.add((byte) (roomId & 0xff));
                    }
                    int suction = appointment.getCleanParam().suction;
                    int humidity = appointment.getCleanParam().humidity;
                    int cleanType = 0;
                    if (suction == 0 && humidity != 0) {
                        cleanType = 2;
                    } else if (suction != 0 && humidity == 0) {
                        cleanType = 1;
                    } else if (suction != 0 & humidity != 0) {
                        cleanType = 0;
                    }

                    bytes.add((byte) (cleanType & 0xff));
                    bytes.add((byte) (suction & 0xff));
                    bytes.add((byte) (humidity & 0xff));

                    //清扫次数，默认为1次
                    int cleanTimes = 1;
                    bytes.add((byte) (cleanTimes & 0xff));
                }

            }
        }

        byte[] sumData;
        byte[] data;

        if (bytes.size() > 0) {
            sumData = new byte[bytes.size()];

            for (int i = 0; i < bytes.size(); i++) {
                sumData[i] = bytes.get(i);
            }

            data = getProtocolPackage((byte) 0x30, sumData);
            sendToDevice("32", StringUtils.byte2hex(data));
        }
    }

    @Override
    public void remoteControl(RemoteControlParam param) {
        RemoteControlParam.Movement moveDirection = param.getMotion();
        int instruct = 0;
        if (moveDirection == RemoteControlParam.Movement.LEFT) {
            instruct = 2;
        } else if (moveDirection == RemoteControlParam.Movement.RIGHT) {
            instruct = 3;
        } else if (moveDirection == RemoteControlParam.Movement.FORWORD) {
            instruct = 0;
        } else if (moveDirection == RemoteControlParam.Movement.BACKWORD) {
            instruct = 1;
        } else if (moveDirection == RemoteControlParam.Movement.STOP) {
            instruct = 4;
        } else {
        }
        sendToDevice("12", instruct);
    }

    @Override
    public void stopRemoteControl() {
        sendToDevice("12", 4);
    }

    @Override
    public void resetComsuptionInfo(ResetComsuptionParam param) {
        String reset = param.getReset();
        String dp = "";
        //自动清扫
        if (reset.equals("resetFilter")) {
            //滤网
            dp = TuyaLaserConstant.RESET_FILTER;
        } else if (reset.equals("resetSidebrush")) {
            //边刷
            dp = TuyaLaserConstant.RESET_EDGE_BRUSH;
        } else if (reset.equals("resetMainbrush")) {
            //主刷
            dp = TuyaLaserConstant.RESET_ROLL_BRUSH;
        } else if (reset.equals("waterTankFilter")) {
            //水箱滤网(x3)
            dp = TuyaLaserConstant.WATER_TANKFI_LTER_RESET;
        } else if (reset.equals("mop")) {
            //拖布
            dp = TuyaLaserConstant.RAG_LIFE_RESET;
        }
        sendToDevice(dp, true);
    }

    @Override
    public void locateDevice() {
        sendToDevice("11", true);
    }

    public byte[] getProtocolPackage1(byte cmd, byte[] data) {
        int protocalPackageLen = data.length + 8;
        byte[] protocalPackage = new byte[protocalPackageLen];
        protocalPackage[0] = ((byte) 0xAB);
        protocalPackage[1] = ((byte) 0x00);
        //数据长度（cmd + data）
        int dataLen = 1 + data.length;
        byte[] lenBytes = StringUtils.intToByteArray(dataLen);
        System.arraycopy(lenBytes, 0, protocalPackage, 2, lenBytes.length);
        protocalPackage[6] = cmd;
        System.arraycopy(data, 0, protocalPackage, 7, data.length);
        byte checkSum = cmd;
        for (int i = 0; i < data.length; i++) {
            checkSum += data[i];
        }
        protocalPackage[protocalPackageLen - 1] = checkSum;
        return protocalPackage;
    }


    public byte[] getProtocolPackage(byte cmd, byte[] data) {
        int protocalPackageLen = data.length + 5;
        byte[] protocalPackage = new byte[protocalPackageLen];
        protocalPackage[0] = ((byte) 0xAA);
        protocalPackage[1] = ((byte) 0x00);
        //数据长度（cmd + data）
        int DataLen = 1 + data.length;
        Log.d("pppppp", "appointment dataLen is " + DataLen);
        protocalPackage[2] = ((byte) DataLen);
        protocalPackage[3] = ((byte) cmd);
        System.arraycopy(data, 0, protocalPackage, 4, data.length);
        byte checkSum = cmd;
        for (int i = 0; i < data.length; i++) {
            checkSum += data[i];
        }
        protocalPackage[protocalPackageLen - 1] = checkSum;
        return protocalPackage;
    }

    public String getWaterStringZw(int water) {
        String waterStr = null;
        switch (water) {
            case 0:
                waterStr = "closed";
                break;
            case 1:
                waterStr = "low";
                break;
            case 2:
                waterStr = "middle";
                break;
            case 3:
                waterStr = "high";
                break;
        }
        return waterStr;
    }

    @Override
    public void uploadLog() {
        sendToDevice(TuyaLaserConstant.UPLOADlOG, true);
    }

    @Override
    public String getFaultMsgByCode(Context context, String faltCode) {
        int srrCode = Integer.parseInt(faltCode);
//        int errCode = getFaultCode(srrCode - 1);
        String errType = "";
        String errDetail = "";
        switch (srrCode) {
            case 1:
                errType = context.getResources().getString(R.string.U_Err_1);
                break;
            case 2:
                errType = context.getResources().getString(R.string.U_Err_2);
                break;
            case 3:
                errType = context.getResources().getString(R.string.U_Err_3);
                break;
            case 4:
                errType = context.getResources().getString(R.string.U_Err_4);
                break;
            case 5:
                errType = context.getResources().getString(R.string.U_Err_5);
                break;
            case 6:
                errType = context.getResources().getString(R.string.U_Err_6);
                break;
            case 7:
                errType = context.getResources().getString(R.string.U_Err_7);
                break;
            case 8:
                errType = context.getResources().getString(R.string.U_Err_8);
                break;
            case 9:
                errType = context.getResources().getString(R.string.U_Err_9);
                break;
            case 10:
                errType = context.getResources().getString(R.string.U_Err_10);
                break;
            case 11:
                errType = context.getResources().getString(R.string.U_Err_11);
                break;
            case 12:
                errType = context.getResources().getString(R.string.U_Err_12);
                break;
            case 13:
                errType = context.getResources().getString(R.string.U_Err_13);
                break;
            case 14:
                errType = context.getResources().getString(R.string.U_Err_14);
                break;
            case 15:
                errType = context.getResources().getString(R.string.U_Err_15);
                break;
            case 16:
                errType = context.getResources().getString(R.string.U_Err_16);
                break;
            case 17:
                errType = context.getResources().getString(R.string.U_Err_17);
                break;
            case 18:
                errType = context.getResources().getString(R.string.U_Err_18);
                break;
            case 19:
                errType = context.getResources().getString(R.string.U_Err_19);
                break;
            case 20:
                errType = context.getResources().getString(R.string.U_Err_20);
                break;
            case 21:
                errType = context.getResources().getString(R.string.U_Err_21);
                break;
            case 22:
                errType = context.getResources().getString(R.string.U_Err_22);
                break;
            case 23:
                errType = context.getResources().getString(R.string.U_Err_23);
                break;
            case 24:
                errType = context.getResources().getString(R.string.U_Err_24);
                break;
            case 25:
                errType = context.getResources().getString(R.string.U_Err_25);
                break;
            case 26:
                errType = context.getResources().getString(R.string.U_Err_26);
                break;
            case 27:
                errType = context.getResources().getString(R.string.U_Err_27);
                break;
            case 28:
                errType = context.getResources().getString(R.string.U_Err_28);
                break;
            case 29:
                errType = context.getResources().getString(R.string.U_Err_29);
                break;

        }
        return errType;
    }

    @Override
    public String getErrorMsgByCode(Context context, String errorCode) {
        Resources res = context.getResources();
        if (YuGongError.ERROR_CODE_NETWORK_ERROR.equals(errorCode)) {
            return res.getString(R.string.U_T_Network_Err);
        } else if (YuGongError.ERROR_CODE_ILLEGAL_USER.equals(errorCode)) {
            return res.getString(R.string.L_T_IllegalUsers);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_COUNT_LIMIT.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_TimesLimit);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_RATE_LIMIT.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_Frequently);
        } else if (YuGongError.ERROR_CODE_REGISTER_USER_EXIST.equals(errorCode)) {
            return res.getString(R.string.L_T_Register_Un_Existed);
        } else if (YuGongError.ERROR_CODE_USER_NOT_EXIST.equals(errorCode)) {
            return res.getString(R.string.U_T_Un_No);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_ERROR.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_No);
        } else if (YuGongError.ERROR_CODE_VERIFY_CODE_EXPIRED.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_Expired);
        } else if (YuGongError.ERROR_CODE_LOGIN_ERROR_PASSWORD.equals(errorCode)) {
            return res.getString(R.string.L_T_Un_Err);
        } else if (YuGongError.ERROR_CODE_SEND_VERIFY_CODE_FAIL.equals(errorCode)) {
            return res.getString(R.string.U_T_Code_No);
        } else {
            return res.getString(R.string.U_UnknownErr);
        }

    }


    protected int getFaultCode(int errCode) {
        //RS01 RS11 GD  LF  不加   其余-1
        int code = 1;
        while (errCode >= 2) {
            errCode = errCode / 2;
            code += 1;
        }
        return code;
    }


    private class GetMultiMapDetailList extends Thread {
        List<CleanRecord> multiMapDetails;
        OkHttpClient okHttpClient;

        public GetMultiMapDetailList(List<CleanRecord> multiMapDetails) {
            this.multiMapDetails = multiMapDetails;
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }

        @Override
        public void run() {
            super.run();
            CountDownLatch countDownLatch = new CountDownLatch(multiMapDetails.size());
            for (int i = 0; i < multiMapDetails.size(); i++) {
                CleanRecord cleanRecord = multiMapDetails.get(i);
                YuGongPayloadData payload = YuGongPayloadData
                        .newBuilder(YuGongConstants.OPT_RESOURCE_DATA_GET)
                        .thing_name(getDeviceId())
                        .data_type("reuse_map")
                        .file_name(cleanRecord.getFileName())
                        .mac(StringUtils.stringReplace(getFirmwareInfo().getMac().toLowerCase()))
                        .build();
                LogUtils.i("  : 获取数据 nn   :" + gson.toJson(payload));
                YuGongSdk.get().getWebService().getData(payload).enqueue(new Callback<YuGongResponse<YuGongRespData>>() {
                    @Override
                    public void onResponse(Call<YuGongResponse<YuGongRespData>> call, retrofit2.Response<YuGongResponse<YuGongRespData>> response) {
                        YuGongResponse<YuGongRespData> result = response.body();
                        LogUtils.i("获取数据 :" + gson.toJson(result));
                        if (result == null) {
                            String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                            return;
                        }
                        if (YuGongConstants.RESP_CODE_SUCCESS == result.getCode()) {
                            YuGongRespData data = result.getData();
                            List<YuGongRespData.FileListBean> listBeans = data.getFile_list();
                            for (YuGongRespData.FileListBean listBean : listBeans) {
                                if (listBean.getData_name().equals("reuseMap.bin")) {
                                    cleanRecord.setUrl(listBean.getData_s3_url());
                                    break;
                                }
                            }
                        } else {
                            String errorInfo = YuGongError.getInterfaceErrorInfo(result.getMsg());
                            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_DATA).result(false).content(errorInfo).send();
                        }

                        countDownLatch.countDown();
                    }

                    @Override
                    public void onFailure(Call<YuGongResponse<YuGongRespData>> call, Throwable t) {
                        String errorInfo = YuGongError.ERROR_CODE_NETWORK_ERROR;
                        countDownLatch.countDown();
                    }
                });
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Event.newBuilder().type(Event.MESSAGE_TYPE_GET_MULTI_MAP_LIST).result(true).content(multiMapDetails).send();
        }
    }

    /**
     * 通过连接获取云存储文件内容
     */
    private class GetCloudFileRunnable extends Thread {
        List<CleanRecord> multiMapDetails;
        OkHttpClient okHttpClient;
        int eventValue;

        public GetCloudFileRunnable(List<CleanRecord> multiMapDetails, int eventValue) {
            this.multiMapDetails = multiMapDetails;
            this.eventValue = eventValue;
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }

        @Override
        public void run() {
            super.run();
            for (int i = 0; i < multiMapDetails.size(); i++) {
                CleanRecord cleanRecord = multiMapDetails.get(i);
                if (cleanRecord.getUrl() != null) {
                    try {
                        Request request = new Request.Builder().url(cleanRecord.getUrl()).get().build();
                        okhttp3.Call call1 = okHttpClient.newCall(request);
                        byte[] data = call1.execute().body().bytes();
                        LogUtils.ls("pathUrl ---response  : " + data);
                        if (eventValue == Event.MESSAGE_TYPE_GET_CLEAN_RECORD_DETAIL) {
                            YxCloudMapDataParser.parseRecord(cleanRecord, data);
                        } else {
                            YxCloudMapDataParser.parseMultiMap(cleanRecord, data);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    }
                }
            }
            Event.newBuilder().type(eventValue).result(true).content(multiMapDetails).send();
        }
    }

    /**
     * 通过连接获取云存储文件内容
     */
    private class GetCleanRecordFileRunnable implements Runnable {
        private CleanRecord record;
        private OkHttpClient okHttpClient;

        public GetCleanRecordFileRunnable(CleanRecord record) {
            this.record = record;
            okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(20, TimeUnit.SECONDS)
                    .build();
        }

        @Override
        public void run() {
            CleanRecord cleanRecord = record;
            String url = cleanRecord.getUrl();
            LogUtils.ls("pathUrl ---request: " + url);
            try {
                Request request = new Request.Builder().url(url).get().build();
                okhttp3.Call call = okHttpClient.newCall(request);
                byte[] data = call.execute().body().bytes();
                LogUtils.ls("pathUrl ---response  : " + data);
                YxCloudMapDataParser.parseRecord(cleanRecord, data);
                Event.newBuilder().type(Event.MESSAGE_TYPE_GET_CLEAN_RECORD_DETAIL).result(true).content(cleanRecord).send();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
        }
    }
}
